﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using ClearUnit.TestRunners.Results;
using Common.Net.Utilities;
using Common.Net.DesignByContract;
using ClearUnit.TestRunners.Starts;
using System.Runtime.CompilerServices;

namespace ClearUnit.TestRunners
{
    public class AssemblyRunner : TestRunnerBase<AssemblyRunResult>
    {
        readonly Assembly _assembly;

        public AssemblyRunner(Assembly assembly, params Action<TestRunInfo>[] interestedListeners)
            : base(interestedListeners)
        {
            RequireArg.NotNull(() => assembly);

            _assembly = assembly;
        }

        protected sealed override AssemblyRunResult RunInternal()
        {
            OnTestInfoEvent(new AssemblyRunStart(_assembly));

            var typeResults = new List<TypeRunResult>();

            foreach (var type in _assembly.GetTypes())
                if (ShouldRunTypeTests(type))
                {
                    var typeRunner = new TypeRunner(type, false, OnTestInfoEvent);
                    var resultCollector = new TestResultCollector(typeRunner);

                    typeRunner.Run();

                    typeResults.AddRange(resultCollector.TypeResults);
                }

            var result = new AssemblyRunResult(_assembly, typeResults);

            OnTestInfoEvent(result);

            return result;
        }

        static bool ShouldRunTypeTests(Type type)
        {
            return type.GetTestMethods().Count() > 0;
        }
    }
}
